home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / TTFHDX / DSMARK.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  14.9 KB  |  552 lines

  1. /*
  2.  *  Dsmark.c
  3.  *    Routines for performing a destructive markbad.
  4.  */
  5.  
  6. /*
  7.  * 23-Nov-87    ml.    just started.
  8.  * 20-Jan-88    ml.    modified for factory version.
  9.  * 14-Sep-89    ml.    Modified to use Rwabs() instead of hread() 
  10.  *            and hwrite().  Will handle both SCSI and
  11.  *            ACSI drives.
  12.  */
  13.  
  14. #include <obdefs.h>
  15. #include <gemdefs.h>
  16. #include <osbind.h>
  17. #include "fhdx.h"
  18. #include "define.h"
  19. #include "part.h"
  20. #include "bsl.h"
  21. #include "addr.h"
  22. #include "lrwabs.h"
  23.  
  24. extern SECTOR *badbuf;
  25.  
  26. extern long addbsl();
  27. extern long nument();
  28. extern int wdesk, hdesk;
  29. extern int maxbadsects;
  30.  
  31. /* Globals */
  32. char *inbuf;        /* data write to disk */
  33. char *readbuf;      /* data read from disk */
  34. int  quitted;        /* 1: Disk testing quit by user */
  35. int  totbad;        /* total num of bad sectors found */
  36. unsigned long pattern;    /* data pattern to test disk with */
  37. long spc;        /* sectors per cylinder */
  38. int  pdev;        /* phys dev num */
  39. int  bad0;        /* TRUE: cylinder 0 is bad */
  40.  
  41.  
  42.  
  43.  
  44. /*
  45.  *  Destructive Markbad for entire device.
  46.  *    Mechanism:
  47.  *        - write data to entire device, read it back, and compare
  48.  *          if there is any difference. (done in markdev())
  49.  *        - all new bad sectors are added to the bad sector list.
  50.  *          (done in markdev())
  51.  *        - repeat above for the number of passes passed in.
  52.  *    Input:
  53.  *        hinfo - information about the device to be marked bad.
  54.  *            e.g. num cylinders, sectors per track, etc....
  55.  *        device - physical device number.
  56.  *        dp - data pattern to test the disk with.
  57.  *    Output:
  58.  *        bsl - bad sector list with added entries if any. (in bsl.h)
  59.  *    Return:
  60.  *        totbad - total number of bad sectors found.
  61.  *        ERROR - if any of the first 3 sectors is bad, or not enough
  62.  *            memory for buffer.
  63.  */
  64. dsmarkbad(hinfo, device, dp)
  65. HINFO *hinfo;        /* hard disk info */
  66. int device;        /* phys dev num */
  67. unsigned long dp;    /* data pattern to test disk */
  68. {
  69.     long bpc;        /* num bytes per cylinder on disk */
  70.     int ret;        /* return code from markdev() */
  71.     unsigned int pass;    /* num passes thru the disk */
  72.     long  temp;        /* for shifting data pattern */
  73.     char numbuf[10];    /* ascii for pass */
  74.     char passbuf[10];
  75.  
  76.     /* Number of sectors per cylinder */
  77.     spc = (long)hinfo->hi_dhc * (long)hinfo->hi_spt;
  78.     bpc = spc*512L;    /* Number of bytes per cylinder */
  79.     pattern = dp;    /* pattern to test disk with */
  80.     pdev = device;    /* device to mark */
  81.     
  82.     /* Allocate big chunk of memory enough for both buffers,
  83.        and split it in two */
  84.     if ((inbuf = (char *)Malloc(bpc << 1)) <= 0) {
  85.         err(nomemory);
  86.         return NOMEM;
  87.     }
  88.     readbuf = inbuf + bpc;
  89.  
  90.     /* Throw up message box to inform user about 
  91.        the processing of the burn-in test.  */
  92.     brninmsg[NUMPASS].ob_spec = "0";
  93.     brninmsg[CYLNUM].ob_spec = "0";
  94.     totbad = (int)nument(VENDOR);
  95.     itoa(totbad, numbuf);
  96.     brninmsg[NUMBAD].ob_spec = numbuf;
  97.     dsplymsg(brninmsg);
  98.          
  99.     pass = 1;        /* about to start pass 1 */     
  100.     temp = 0;
  101.     quitted = 0;    /* procedure not quitted yet */
  102.     
  103.     /* Loop forever until some specified key is hit */
  104.     while (1) {
  105.     fillbuf(inbuf, bpc, pattern);
  106.         itoa(pass, passbuf);
  107.         brninmsg[NUMPASS].ob_spec = passbuf;
  108.         objc_draw(brninmsg, PASSBOX, MAX_DEPTH, 0, 0, wdesk, hdesk);
  109.         if ((ret = markdev(hinfo->hi_cc))
  110.             < 0) {
  111.             goto wrapup;
  112.     } else {
  113.         if (quitted) {
  114.             ret = totbad;
  115.             goto wrapup;
  116.         }
  117.     }
  118.     pass++;
  119.     
  120.     /* Shift data pattern */
  121.     temp = pattern >> 28;
  122.     pattern = (pattern << 4) | temp;
  123.     }
  124. wrapup:
  125.     erasemsg();
  126.     Mfree((long)inbuf);
  127.     return (ret);
  128. }
  129.  
  130.  
  131. /*
  132.  *  Fill up a character buffer with the given pattern.
  133.  *    Input:
  134.  *        buf - buffer to be filled.
  135.  *        size - size of buffer in bytes.
  136.  *        dp - a 4-byte data to fill the buffer.
  137.  *    Output:
  138.  *        buf - buffer filled with the given pattern.
  139.  */
  140. fillbuf(buf, size, dp)
  141. char *buf;
  142. long size;
  143. long dp;
  144. {
  145.     long i;    /* index */
  146.     
  147.     for (i = 0L; i < size; i += 4L)
  148.     *(long *)&buf[i] = dp;
  149. }
  150.  
  151.  
  152. /*
  153.  *  Markdev - Find bad sectors on a hard disk and record them in the Bad
  154.  *          Sector List.
  155.  *    Mechanism:
  156.  *        - write some given data to the entire device cylinder by
  157.  *          cylinder.
  158.  *        - read from the device cylinder by cylinder but in reverse
  159.  *          order.
  160.  *        - as data are read from the device, compare the written data
  161.  *          with the data read.  
  162.  *        - if there is any write, read or data error in a sector, that
  163.  *          sector will be considered bad.  (data error means data read
  164.  *          is different from data written.)
  165.  *        - add the bad sectors to the bad sector list.
  166.  *    Input:
  167.  *        cyl - number of cylinders on the device. 
  168.  *    Output:
  169.  *        bsl - an updated bad sector list (ie. with newly found bad
  170.  *              sectors added to it).
  171.  *    Return:
  172.  *        ERROR - Any sector in cylinder 0 is bad.
  173.  *              - Number of bad sectors 
  174.  *                > Maximum number of bad sectors allowed.
  175.  *    Comments:
  176.  *        To test both the media and the mechanics of the disk:
  177.  *    - on even cycles we'll do a sequential test.
  178.  *      (i.e. markbad cylinder 0 --> last cylinder sequentially.)
  179.  *    - on odd cycles we'll do a random test.
  180.  *      (i.e. seek to random cylinder and markbad that one.)
  181.  *
  182.  */
  183. markdev(cyl)
  184. int cyl;    /* num cylinders on device */
  185. {
  186.     unsigned int halfcyl, sechalf;    /* counter */
  187.     int ret;                /* return code from markcyl() */
  188.  
  189.     sechalf = halfcyl = cyl >> 1;    
  190.     if (cyl % 2)
  191.         halfcyl++;
  192.  
  193.     /* Markbad first half of device */
  194.     if ((ret = markhalf(halfcyl, 0)) < 0)
  195.         return ret;
  196.     if (quitted)
  197.         return OK;
  198.         
  199.     /* Markbad second half of device */
  200.     if ((ret = markhalf(halfcyl, sechalf)) < 0)
  201.         return ret;
  202.     return OK;
  203. }
  204.  
  205.  
  206.  
  207. /*
  208.  *  Markbad half of a device.
  209.  */
  210. markhalf(numcyl, stcyl)
  211. unsigned int numcyl;    /* number of cylinders in half a device */
  212. unsigned int stcyl;    /* starting cylinder number for that half device */
  213. {
  214.     unsigned int cylcnt, cyl1, cyl2;
  215.     char numbuf[10];
  216.     int ret;
  217.     
  218.     cyl1 = stcyl;
  219.     cylcnt = numcyl >> 1;
  220.     cyl2 = stcyl + cylcnt;
  221.     if (numcyl % 2)
  222.         cylcnt++;
  223.         
  224.     while (cylcnt) {
  225.     itoa(cyl1, numbuf);
  226.     brninmsg[CYLNUM].ob_spec = numbuf;
  227.     objc_draw(brninmsg, CYLBOX, MAX_DEPTH, 0, 0, wdesk, hdesk);
  228.     if ((ret = markcyl(cyl1)) < 0) {
  229.         return ret;
  230.     }
  231.     else if (quitted) {
  232.         /* Test cylinder 0 again */
  233.         if ((ret = markcyl(0)) < 0)
  234.             return ret;
  235.         return OK;
  236.     }
  237.     cyl1++;
  238.     
  239.     itoa(cyl2, numbuf);
  240.     brninmsg[CYLNUM].ob_spec = numbuf;
  241.     objc_draw(brninmsg, CYLBOX, MAX_DEPTH, 0, 0, wdesk, hdesk);
  242.     if ((ret = markcyl(cyl2)) < 0) {
  243.         return ret;
  244.     }
  245.     else if (quitted) {
  246.         /* Test cylinder 0 again */
  247.         if ((ret = markcyl(0)) < 0)
  248.             return ret;
  249.         return OK;
  250.     }
  251.     cyl2++;
  252.     cylcnt--;
  253.     }
  254.     return OK;
  255. }
  256.  
  257.  
  258. /*
  259.  *  Mark bad one cylinder.
  260.  *    Input:
  261.  *        cylnum - cylinder to be tested.
  262.  *    Output:
  263.  *        bsl - an updated bad sector list (ie. with newly found bad
  264.  *              sectors added to it).
  265.  *    Return:
  266.  *        ERROR - Any sector in cylinder 0 is bad.
  267.  *              - Number of bad sectors 
  268.  *                > Maximum number of bad sectors allowed.
  269.  *    Comments:
  270.  *        This procedure could be interrupted by the following keycodes:
  271.  *        Ctrl-S - Suspend running of procedure.
  272.  *        Ctrl-Q - Quit from procedure.
  273.  *        Ctrl-R - Restore running of procedure.
  274.  */
  275. markcyl(cylnum)
  276. unsigned int cylnum;    /* cylinder number */
  277. {
  278.     long olderr, crerr();
  279.     SECTOR start, stcnt;    /* where to start writing or reading */
  280.     unsigned int sectcnt;    /* counters */
  281.     unsigned int nbad;        /* num bad sectors so far */
  282.     int ret;            /* return code */
  283.     int clean;            /* indicate if cylinder has any bad sector */
  284.     BYTE key;            /* keyboard input */
  285.     char chkeybd();
  286.     
  287.     olderr = Setexc(0x101, crerr);  /* Handle critical error ourselves */
  288.     
  289.         
  290.     /*------------------------------------------------------------*/
  291.     /*  Write lots of sectors (one cylinder worth) at a time.     */
  292.     /*  If write error, loop through sectors within that cylinder */
  293.     /*  to find out exactly which sector(s) is bad, and add it to */
  294.     /*  the bad sector list if it's not already there.          */
  295.     /*------------------------------------------------------------*/
  296.     
  297.     bad0 = FALSE;    /* cylinder 0 is not bad */
  298.     ret = OK;        /* everything is OK now... */
  299.         
  300.     /* Check for keyboard input */
  301.     if ((key = chkeybd()) != NOKEY && key != CTRLR) {
  302.     if (key == CTRLS) {
  303.         while (1) {
  304.             if ((key = chkeybd()) == CTRLR || key == CTRLQ)
  305.                 break;
  306.         }
  307.     }
  308.     if (key == CTRLQ) {
  309.         quitted = 1;
  310.         ret = OK;
  311.         goto badnews;
  312.     }
  313.     }
  314.     
  315.     start = (SECTOR)cylnum * spc;
  316.     
  317.     nbad = 0;    /* no bad sectors found yet */
  318.     if (Lrwabs(PHYSWRT, inbuf, (unsigned int)spc, start, pdev+2) != 0) {
  319.         sectcnt = (unsigned int)spc;
  320.         stcnt = start;
  321.         while (sectcnt) {
  322.             if (Lrwabs(PHYSWRT, inbuf, 1, stcnt, pdev+2) != 0) {
  323.                  *(badbuf+nbad) = stcnt;    /* store bad sector num */
  324.                  nbad++;
  325.               if (stcnt < spc) {
  326.                   bad0 = TRUE;
  327.                      ret = err(cyl0bad);
  328.                   goto addwr;
  329.               }
  330.             }
  331.             stcnt++;
  332.             sectcnt--;
  333.         }
  334.     }
  335.  
  336. addwr:
  337.     if (nbad) {    /* there are bad sectors found not added to BSL yet */
  338.     if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  339.         goto badnews; 
  340.     }
  341.     if (ret > 0) {
  342.         totbad += ret;    /* increment num bad sectors existing */
  343.         prnbad();
  344.     }
  345.     if (totbad > maxbadsects || bad0 == TRUE) {
  346.         ret = ERROR;
  347.         goto badnews;
  348.     }
  349.     }
  350.     
  351.     /*-----------------------------------------------------------*/
  352.     /* Read lots of sectors (one cylinder worth) at a time.      */
  353.     /* If read error, loop through sectors within that cylinder  */
  354.     /* to find out exactly which sector(s) is bad, and add it to */
  355.     /* the bad sector list if it's not already there.         */
  356.     /*                                 */
  357.     /* Data read is compared to data written.  If there is any   */
  358.     /* discrepancy within a sector, mark that sector as bad in   */
  359.     /* the bad sector list.                     */
  360.     /*-----------------------------------------------------------*/
  361.  
  362.     /* Check for keyboard input */
  363.     if ((key = chkeybd()) != NOKEY && key != CTRLR) {
  364.     if (key == CTRLS) {
  365.         while (1) {
  366.             if ((key = chkeybd()) == CTRLR || key == CTRLQ)
  367.                 break;
  368.         }
  369.     }
  370.     if (key == CTRLQ) {
  371.         quitted = 1;
  372.         ret = OK;
  373.         goto badnews;
  374.     }
  375.     }
  376.     
  377.     nbad = 0;    /* no bad sectors for this cylinder yet */
  378.     fillbuf(readbuf, spc<<9, 0L);
  379.     if (Lrwabs(PHYSREAD, readbuf, (unsigned int)spc, start, pdev+2) != 0) {
  380.     sectcnt = (unsigned int)spc;
  381.         stcnt = start;
  382.         while (sectcnt) {
  383.         fillbuf(readbuf, 512L, 0L);
  384.             if (Lrwabs(PHYSREAD, readbuf, 1, stcnt, pdev+2) != 0) {
  385.                  *(badbuf+nbad) = stcnt;    /* store bad sector num */
  386.                  nbad++;
  387.                 if (stcnt < spc) {
  388.                     bad0 = TRUE;
  389.                     ret = err(cyl0bad);
  390.                   goto addrd;
  391.               }
  392.             } else {
  393.                 if (!blktst(readbuf, pattern, 512L)) {
  394.                     *(badbuf+nbad) = stcnt;    /* store bad sector num */
  395.                     nbad++;
  396.                     if (stcnt < spc) {
  397.                         bad0 = TRUE;
  398.                   ret = err(cyl0bad);
  399.                       goto addrd;
  400.                   }
  401.                 }
  402.             }
  403.             stcnt++;
  404.             sectcnt--;
  405.         }
  406.         clean = 0;
  407.     } else {
  408.         clean = 1;
  409.     }
  410.         
  411. addrd:
  412.     if (nbad) { /* there are bad sectors found not added to BSL yet */
  413.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  414.             goto badnews;
  415.         }
  416.         if (ret > 0) {
  417.             totbad += ret;    /* incr num bad sectors added to BSL */
  418.             prnbad();
  419.         }
  420.     if (totbad > maxbadsects || bad0 == TRUE) {
  421.         ret = ERROR;
  422.     }
  423.     } else if (clean) {
  424.         /* Check for keyboard input */
  425.         if ((key = chkeybd()) != NOKEY && key != CTRLR) {
  426.         if (key == CTRLS) {
  427.         while (1) {
  428.                 if ((key = chkeybd()) == CTRLR || key == CTRLQ)
  429.                 break;
  430.         }
  431.         }
  432.         if (key == CTRLQ) {
  433.         quitted = 1;
  434.         ret = OK;
  435.         goto badnews;
  436.         }
  437.     }
  438.     
  439.     /* compare data read with data written, record bad sectors if any */
  440.         if ((ret = cmpdata(start)) > 0) {
  441.             totbad += ret;    /* incr num bad sectors added to BSL */
  442.             prnbad();
  443.         if (totbad > maxbadsects || bad0 == TRUE) {
  444.         ret = ERROR;
  445.         goto badnews;
  446.         }
  447.         } else {
  448.             goto badnews;
  449.         }
  450.     }
  451. badnews:
  452.     Setexc(0x101, olderr);
  453.     if (ret < 0)        /* if an error occurs, */
  454.         return(ret);        /*    return the error */
  455.     else return OK;    /* else return number of bad sectors found. */
  456. }
  457.  
  458.  
  459.  
  460. /*
  461.  *  Compare data read with data written of a cylinder, and mark sectors
  462.  *  with data error in the bad sector list.
  463.  *    Input:
  464.  *        start - starting physical sector number of the cylinder.
  465.  *    Output:
  466.  *        bsl - an updated bad sector list with the newly found bad
  467.  *              sectors marked in it.
  468.  */
  469. cmpdata(start)
  470. SECTOR start;    /* phys sect num of where cylinder starts */
  471. {
  472.     unsigned int cnt;        /* index into databuf, counter */
  473.     int nbad;            /* num bad sectors found so far */
  474.     int mbad;            /* total num bad sectors found in cylinder */
  475.     int ret;            /* return code from addbsl() */
  476.     char *buf;
  477.     
  478.     mbad = nbad = 0;    /* no bad sectors found yet */
  479.     
  480.     /* Test whole cylinder first, if OK, ship it.  
  481.        Return 0L if no bad sectors found. */
  482.     if (blktst(readbuf, pattern, spc<<9))
  483.         return 0;
  484.         
  485.     buf = readbuf;
  486.     for (cnt = 0; cnt < spc; cnt++) {
  487.         if (!blktst(buf, pattern, 512L)) {
  488.         *(badbuf+nbad) = start + cnt;    /* store bad sector num */
  489.         nbad++;
  490.         if ((start+cnt) < spc) {
  491.             bad0 = TRUE;
  492.             err(cyl0bad);
  493.             goto addcd;
  494.         }
  495.     }
  496.     buf += 512L;
  497.     }
  498. addcd:
  499.     if (nbad) {    /* bad sectors found but not added to BSL yet */
  500.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  501.             return ret;
  502.         }
  503.         mbad += ret;    /* incr num bad sectors added to BSL */
  504.     }
  505.     return(mbad);
  506. }
  507.  
  508.  
  509.  
  510.  
  511. /*
  512.  *  Update number of bad sectors found during Destructive Markbad in
  513.  *  the dialogue box.
  514.  */
  515. prnbad()
  516. {
  517.     char numbuf[10];
  518.     
  519.     itoa(totbad, numbuf);
  520.     brninmsg[NUMBAD].ob_spec = numbuf;
  521.     objc_draw(brninmsg, NBADBOX, MAX_DEPTH, 0, 0, wdesk, hdesk);
  522. }
  523.  
  524.  
  525. /*
  526.  *  Check if any key is input from the keyboard.
  527.  *    Key code looking for:
  528.  *        Ctrl-S - Suspend running of procedure.
  529.  *        Ctrl-Q - Quit from procedure.
  530.  *        Ctrl-R - Restore running of procedure.
  531.  *        Any other or no key - no effect.
  532.  *    Return:
  533.  *        NOKEY - if no key is input, or key input is not
  534.  *            what we are looking for.
  535.  *        CTRL? - where ? could be S, Q or R.
  536.  */
  537. char
  538. chkeybd()
  539. {
  540.     char key;        /* key being input */
  541.  
  542.     if (Bconstat(2)) {        /* 2: CONSOLE */
  543.         if((key = Bconin(2)) != CTRLS
  544.            && key != CTRLQ
  545.            && key != CTRLR)
  546.         key = NOKEY;
  547.     } else {
  548.         key = NOKEY;
  549.     }
  550.     return key;
  551. }
  552.